#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 9;
int T;
int n, m, L, V;
int d[N], v[N], a[N], p[N];
int tot;
int cut;
int mina;
bool vis[N];
bool cmp(int x, int y){
    return x >= y;
}
void init(){
    memset(d, 0, sizeof d);
    memset(v, 0, sizeof v);
    memset(a, 0, sizeof a);
    memset(p, 0, sizeof p);
    scanf("%d%d%d%d", &n, &m, &L, &V);
    for(int i = 1; i <= n; i++)
        scanf("%d%d%d", &d[i], &v[i], &a[i]);
    for(int i = 1; i <= m; i++)
        scanf("%d", &p[i]);
    tot = 0;
    cut = 0;
}
bool judge(int x, int y){
    int i, j;
    for(i = 1; i <= m - 1; i++){
        if(p[i] <= x && p[i + 1] >= x)break;
    }
    for(j = m; j >= 2; j--){
        if(p[j] >= x && p[j - 1] <= x)break;
    }
    if(i <= j){
        for(i; i <= j; i++)vis[i]++;
        return true;
    }
    return false;
}
int dfs(int tot, int num, int sum){
    if(vis[num] >= tot)return 1;
    return dfs(tot - vis[num], num + 1, sum + 1) + 1;
}
void search(){
    bool flag;
    for(int i = 1; i <= n; i++){
        if(a[i] > 0){
            int x = (int)((V * V - v[i] * v[i])/(2 * a[i])) + d[i];
            if(x < p[m] && x >= p[1])
                tot++;
                flag = true;


        }
        if(a[i] == 0){
            if(v[i] <= V || d[i] >= p[m] || d[i] <= p[1])continue;
            flag = true;
            tot++;
        }
        if(a[i] < 0){
            if(v[i] <= V)continue;
            int x = (int)((V * V - v[i] * v[i])/(2 * a[i]));
            if(judge(x, d[i])){
                mina++;
                tot++;

            }
        }
    }
    sort(vis + 1, vis + n + 1, cmp);
    for(int i = 1; i <= n; i++){
        if(!vis[i])break;
    }
    cut = m - dfs(mina, 1, 0);
    if(flag == true) cut--;
    printf("%d %d\n", tot, cut);
}
int main(){
    freopen("detect.in", "r", stdin);
    freopen("detect.out", "w", stdout);
    scanf("%d", &T);
    for(int i = 1; i <= T; i++){
        init();
        search();
    }
    fclose(stdin);
    fclose(stdout);
    return 0;
}
